/* Util Functions */
function createXmlHttpRequest() {
    if (window.XMLHttpRequest) { //None-IE
        return new XMLHttpRequest();
    }
    else {
        return null;
    }
}

/* Class UEConsole */
//Constructor
var UELogin = function(OwnerConsole) {
    this.OwnerConsole = OwnerConsole;
    document.getElementById('password').addEventListener('keydown', this, false);
    document.getElementById('login').addEventListener('click', this, false);
}

//Event Handler
UELogin.prototype.handleEvent = function(evt) {
    switch (evt.type) {
        case 'keydown':
            if (evt.keyCode == 13) {
                evt.preventDefault();
                this.OwnerConsole.DoLogin();
            }
            break;  //end of keydown
        case 'click':
            if (evt.target.getAttribute('id') == 'login') {
                this.OwnerConsole.DoLogin();
            }
            break;  //end of click
        default:
    } //End of switch
}
/* End of Class UEConsole */

/* Class UEConsole */
//Constructor
var UEConsole = function(console) {
    this.srcWidth = 1280;
    this.srcHeight = 768;
    this.heartbeatInterval = 1000;
    this.login_url = "/cgi-bin/login.cgi";
    this.update_url = "/cgi-bin/update.cgi";
    this.action_url = "/cgi-bin/action.cgi";

    this.m_Login = new UELogin(this);

    this.console = document.getElementById("ueconsole");
    this.console.width = this.srcWidth;
    this.console.height = this.srcHeight;
    this.console.style.left = 0;
    this.console.style.top = 0;
    this.console.addEventListener('click', this, false);

    this.token = 0;
    this.ueid = 0;

    this.console = console;
    this.image = null;
}

UEConsole.prototype.Start = function(PostLogin, PostUpdate, PostImageLoad) {
    document.getElementById('ueconsole_container').style.display = 'none';
    document.getElementById('uelogin_container').style.display = 'block';

    this.PostLogin = PostLogin;
    this.PostUpdate = PostUpdate;
    this.PostImageLoad = PostImageLoad;
}

UEConsole.prototype.DoLogin = function() {
    var password = document.getElementById('password').value;
    /* TODO: URL encoding for password */

    var xmlHttpRequest = createXmlHttpRequest();
    xmlHttpRequest.open("POST", this.login_url, false);
    xmlHttpRequest.send("password=" + password);

    if (xmlHttpRequest.status == 200) {
        var result = eval("(" + xmlHttpRequest.responseText + ")");
        if (result.status == 0) {
            this.token = result.token;

            document.getElementById('ueconsole_container').style.display = 'block';
            document.getElementById('uelogin_container').style.display = 'none';

            this.PostLogin();
        }
        else {
            alert(result.description);
        }
    }
    else {
        alert('Login Failed!');
    }
}

UEConsole.prototype.DoUpdate = function() {
    this.updateHttpRequest = createXmlHttpRequest();

    this.updateHttpRequest.onreadystatechange = this.PostUpdate;
    this.updateHttpRequest.open("POST", this.update_url, false);
    this.updateHttpRequest.send("token=" + this.token + "&ueid=" + this.ueid);

    
}

UEConsole.prototype.LoadUpdateData = function() {
    if (this.updateHttpRequest.readyState == 4) {
        if (this.updateHttpRequest.status == 200) {
            var result = eval("(" + this.updateHttpRequest.responseText + ")");
            if (result.status == 0) {
                var ueid = result.ueid;

                if (this.console.width != result.width)
                    this.console.width = result.width;

                if (this.console.height != result.height)
                    this.console.height = result.height;

                for (var i = 0; i < result.count; i++) {
                    this.image = new Image();
                    this.image.onload = this.PostImageLoad;
                    this.image.src = result.item[i].data;
                }
            }
            else {
                alert(result.description);
            }
        }
        else {
            /* TODO: error handle */
        }
    }
}

UEConsole.prototype.DoDrawImage = function() {
    var context = this.console.getContext("2d");
    context.drawImage(this.image, 0, 0);
}

UEConsole.prototype.HandleMouseClick = function(x, y) {
    var xmlHttpRequest = createXmlHttpRequest();
    
    xmlHttpRequest.open("POST", this.action_url, false);
    xmlHttpRequest.send("token=" + this.token + "&ueid=" + this.ueid + "&action=1&x=" + x + "&y=" + y);

    if (xmlHttpRequest.status == 200) {
        var result = eval("(" + xmlHttpRequest.responseText + ")");
        if (result.status == 0) {
            var ueid = result.ueid;

            if (this.console.width != result.width)
                this.console.width = result.width;

            if (this.console.height != result.height)
                this.console.height = result.height;

            for (var i = 0; i < result.count; i++) {
                this.image = new Image();
                this.image.onload = this.PostImageLoad;
                this.image.src = result.item[i].data;
            }
        }
        else {
            alert(result.description);
        }
    }
    else {
        /* TODO: error handle */
    }
}

UEConsole.prototype.handleEvent = function(evt) {
    switch (evt.type) {
        case 'click':
            var x = evt.pageX - this.console.offsetLeft;
            var y = evt.pageY - this.console.offsetTop;
            this.HandleMouseClick(x, y);
            break;  //end of click
        default:
    } //End of switch
}

function PostLogin() {
    DoUpdate();
}

function PostUpdate() {
    theConsole.LoadUpdateData();
}

function DoUpdate() {
    theConsole.DoUpdate();
}

function DoDrawImage() {
    theConsole.DoDrawImage();
    setTimeout(DoUpdate, theConsole.heartbeatInterval);
}

/* Init */
var theConsole = new UEConsole(document.getElementById("ueconsole"));
theConsole.Start(PostLogin, PostUpdate, DoDrawImage);